#include "coordenadas.h"
#include <cstdlib>
#include <string.h>

/*Constructor */
coordenadas::coordenadas()
{
        distRecorridTot = 0.0;
        distRecorrid = 0.0;
        distRestante = 0.0;
        VelocidadActual = 0.0;
        VelocidadPromedioTotal = 0.0;
        VelocidadPromedioActual = 0.0;
        tiempoDeRecorrido = 0.0;
  /*      ingresarLAT();
        ingresarLON();
        CrearVistaMap();
        puntoInicial.lat = latitud.metro;
        puntoInicial.lon = longitud.metro;*/
        distRecorrid = 0.0;
        tiempoDeRecorrido = 0.0;

}

coordenadas::~coordenadas()
{


}

void coordenadas::ingresarLAT(struct terna actuales)
{
    printf("Latitud :\n");
    this->ingreso_inicio = 1;
    //this->puntoAnterior.lat = this->latitud.metro;
        //this->ingresar(&this->latitud);
    this->latitud = actuales;
    this->CalcularDists(1, &this->latitud);
    this->puntoActual.lat = this->latitud.metro;
}

void coordenadas::ingresarLON(struct terna actuales)
{
    printf("Longitud :\n");
    //this->puntoAnterior.lon = this->longitud.metro;
    //this->ingresar(&this->longitud);
    this->longitud = actuales;
        this->CalcularDists(0, &this->longitud);
        this->puntoActual.lon = this->longitud.metro;
}

void coordenadas::mostrarDatos()
{
    printf("-----------------------------------------\n");
    printf("\tEl tiempo desde el inicio del recorrido es: %f\n", tiempoDeRecorrido);
    /*printf("\tLa hora de arribo yendo a la velocidad promedio actual. \n",);
    printf("\tIndicar a que velocidad promedio hay que viajar a partir de ese instante para poder llegar a destino a una determinada hora seleccionada por el usuario \n",);
    */
    printf("\tLa velocidad promedio desde el inicio del recorrido %f Km/H\n",VelocidadPromedioTotal);
    printf("\tLa distancia restante: %f Km.\n", distRestante);
    printf("\tLa distancia recorrida en el ultimo tramo: %f Mts.\n",distRecorrid*1000);
    printf("\tLa velocidad actual es de: %f Km/h\n", VelocidadActual);
    printf("\tLa distancia recorrida total: %f Km. \n", distRecorridTot);
    printf("-----------------------------------------\n");
}

void coordenadas::mostrarLAT()
{
    printf("Latitud :\n");
        this->mostrar(this->latitud);
}

void coordenadas::mostrarLON()
{
    printf("Longitud :\n");
        this->mostrar(this->longitud);
}

void coordenadas::ingresar(struct terna *gra)
{
        printf("Ingrese los grados:");
        scanf("%f", &gra->grados);
        fflush(stdin);
        printf("Ingrese los minutos:");
        scanf("%f", &gra->minutos);
        fflush(stdin);
        printf("Ingrese los segundos:");
        scanf("%f", &gra->segundos);
        fflush(stdin);
        printf("\n");
}

void coordenadas::mostrar(struct terna gra)
{
        printf("-----------------------------------------------\n");
        printf("%f °\n", gra.grados);
        printf("%f '\n", gra.minutos);
        printf("%f ''\n", gra.segundos);
        printf("La distancia al eje de cual se esta midiendo es : %f km\n", gra.metro/1000);
        printf("------------------------------------------------\n");
}

/* Si se envia un 1 se calculara la latitud, en caso contrario, la longitud*/

void coordenadas::CalcularDists(int opc, struct terna *conv)
{
    float totsegs = 0 , equivalencia;
    struct terna *cord;
    cord = conv;
    if(opc == 1)
    {
        equivalencia = eqsegLAT;
    }
    else
    {
        /* Aqui se corrige el radio para la latitud en al que se encuentra
           Tomese al modulo de la latitud ya que sino la raiz sera negativa o muy grande */
        float tmp = this->latitud.metro/1000;
        tmp = (radioLAT*radioLAT) - (tmp*tmp) ;
        tmp = sqrt(tmp);
        equivalencia = tmp*1000/360/60/60;
    }
    /* Paso los grados a segundos.. y luego le sumo los minutos pasados a segundos mas los segundos*/
    totsegs = cord->grados * 60*60;
    totsegs += cord->minutos*60;
    totsegs += cord->segundos;
    cord->metro = totsegs * equivalencia;
}

void coordenadas::CrearVistaMap()
{
    double lat1, long1;
    lat1 = this->latitud.grados + this->latitud.minutos/60 + this->latitud.segundos/60/60;
    long1 = this->longitud.grados + this->longitud.minutos/60 + this->longitud.segundos/60/60;

    char *txtcord , tmp2[50], caracter;
    FILE *tmp, *pagina;
    pagina = fopen("pagina.html", "w");
    if(pagina == NULL)
    {
        QMessageBox *asd = new QMessageBox();
        asd->setText("Error al crear el archivos de pagina");
        asd->show();
        delete asd;

        printf("Error al crear el archivos de pagina\n");
        fclose(pagina);
    }
    if((tmp=fopen("part1", "a+"))==NULL)
    {
        QMessageBox *asd = new QMessageBox();
        asd->setText("Error al abrir la primer parte");
        asd->show();
        delete asd;
        printf("Error al abrir la primer parte\n");
    }
    else
    {
        rewind(tmp);

            do{
            caracter= getc(tmp);
            if(caracter!=EOF)
                {
                putc(caracter, pagina);
                }
            }while(!feof(tmp));
    }

    /*gcvt transforma un valor double (lat1 en este caso) a un valor tipo char, utiliza una cant de digitos y el valor en char lo devuelve,
    o lo almacena en el tercer argumento un puntero a char*/
    //tmp2 = gcvt(lat1, numero_digitos, txtcord);
    sprintf(tmp2, "%5.20f", lat1);
    // Sub rutina para intercambiar la coma por el punto
    char *arreglado;
    arreglado = strchr(tmp2, ',');
    if(arreglado != NULL)
    {
        *arreglado = '.';
    }

    //Fin de la sub rutina

    fprintf(pagina, "%s", tmp2);
    fprintf(pagina, ",", NULL);
    //tmp2= gcvt(long1, numero_digitos, txtcord);
    sprintf(tmp2, "%5.20f", long1);

    // Intercambiamos la coma por el punto
    arreglado = strchr(tmp2, ',');
    if(arreglado != NULL)
    {
        *arreglado = '.';
    }

    //Fin del intercambio
    fprintf(pagina, "%s", tmp2);
    fclose(tmp);
    if((tmp=fopen("part2", "a+"))==NULL)
    {
        QMessageBox *asd = new QMessageBox();
        asd->setText("Error al abrir la segunda parte");
        asd->show();
        delete asd;
        printf("Error al abrir la segunda parte\n");
    }
    else
        {
            rewind(tmp);
            do{
            caracter= getc(tmp);
            if(caracter!=EOF){
            putc(caracter, pagina);}
            }while(!feof(tmp));
        }
    fflush(pagina);
    fclose(tmp);
    fclose(pagina);
    }

/* Esta funcion (CVelocidad), se encarga de realizar los calculos para saber la velocidad a la que se encuentra viajando, esto se hace,
* hallando la diferencia de distancia(equivale a la distancia recorrida), y luego dividirla por el tiempo que llevo recorrer esa distancia
*/

double coordenadas::DistanciaRestante(struct VectorMetro actual, struct VectorMetro anterior)
{
    double componentelat, componentelon, resultado;

    componentelat = actual.lat - anterior.lat;
    componentelon = actual.lon - anterior.lon;

    componentelat = componentelat*componentelat;
    componentelon = componentelon*componentelon;
    resultado = sqrt( componentelat+componentelon );
    resultado /= 1000;
    return(resultado);
}

void coordenadas::CalcularDistanciaRestante(void)
{
    distRestante = DistanciaRestante(puntoFinal, puntoActual);

}

void coordenadas::SeleccionarDestino(struct terna lati1, struct terna longi1)
{
    //printf("Ingrese las coordenadas del destino\n");
    /* Creamos unas estructuras temporales para contener los datos actuales mientras trabajamos con la posicion de destino*/
    struct terna tempLat, tempLong;
    /* Ingresamos la posicion actual */
    tempLat = lati1;
    tempLong = longi1;
    /* Realizamos los calculos */
    this->CalcularDists(1, &tempLat);
    this->CalcularDists(0, &tempLong);
    /* Los guardamos como coordenandas de destino */
    this->puntoFinal.lat = tempLat.metro;
    this->puntoFinal.lon = tempLong.metro;

    this->CalcularDistanciaRestante();

}

void coordenadas::CargarSiguienteMov(struct terna lati1, struct terna longi1)
{
    this->puntoAnterior.lat = this->puntoActual.lat;
    this->puntoAnterior.lon = this->puntoActual.lon;
    this->tiempoDeRecorrido += tiempoActualizacion;
    float tmpVel = this->VelocidadActual;


    this->ingresarLAT(lati1);
    this->ingresarLON(longi1);

    float TempDist;
    TempDist = this->DistanciaRestante(this->puntoActual, this->puntoAnterior);
    /* La velocidad queda dada en Kilometros por segundo */
    this->VelocidadActual = (TempDist*(60/tiempoActualizacion)*60);
    this->VelocidadPromedioActual = ((tmpVel + this->VelocidadActual)/2)*(60/tiempoActualizacion)*60;
    this->distRecorridTot += TempDist;
    this->distRecorrid = TempDist;

    /*Velocidad prom total*/
    this->VelocidadPromedioTotal = (this->distRecorridTot / this->tiempoDeRecorrido)*60*60;

    this->CalcularDistanciaRestante();
    this->CalcularHoraArribo(0);

}

void coordenadas::CalcularHoraArribo(float veloc)
{
    /* Funcion que calcula la hora de arribo si se mantiene la velocidad promedio actual */
    float *Tiem;
    if(veloc==0)
    {
        veloc = this->VelocidadActual;
        Tiem = &this->TiempitoArriboProm;
    }
    else
    {
        Tiem = &this->TiempitoArribo;
    }
     *Tiem = this->distRestante/veloc;
     *Tiem *= 60;
    //printf("Manteniendo la velocidad promedio actual llegara a destino en: %f Minutos\n",TiempitoArribo);
}

void coordenadas::CalcularVelocidadParaArribo(float tiempo_minutos)
{

    //printf("Ingrese el tiempo, en minutos,en el que desea arribar a destino: \n");

    this->VelocidadResultante = this->distRestante/tiempo_minutos;
    this->VelocidadResultante *= 60;
    //printf("Usted debera Viajar a %f Km/h para llegar en %f Minutos a destino\n", VelocidadResultante, Tiempo);
}

